package ie.ul.breakthrough;

import java.util.ArrayList;

public class MiniMaxPlayer extends Player {

	public static final double MAX_EVAL = 1000000.0;

	public static final double MIN_EVAL = -1000000.0;

	private BreakthroughMove bestMove;

	public MiniMaxPlayer(String pName) {
		super(pName);
	}

	@Override
	public void initialize(char pColour) {
		colour = pColour;
	}

	@Override
	public BreakthroughMove makeMove(Breakthrough game) {
		maxPlayerMove(game, 4);
		return bestMove;
	}

	private double maxPlayerMove(Breakthrough game, int depth) {
		ArrayList<BreakthroughMove> possibleMaxMoves = game
				.generateMoves(colour);

		if (game.isGameOver() || possibleMaxMoves.size() == 0) {
			return MIN_EVAL;
		}

		double bestEval = MIN_EVAL;
		double eval = MIN_EVAL;
		double minPlayerEval = MIN_EVAL;

		for (BreakthroughMove move : possibleMaxMoves) {
			eval = MIN_EVAL;
			minPlayerEval = MIN_EVAL;

			Breakthrough nextBoard = new Breakthrough(game);
			nextBoard.makeMove(colour, move);
			eval = evalFunction(nextBoard);

			if (eval > bestEval) {
				bestEval = eval;
				bestMove = move;
			}

			minPlayerEval = minPlayerMove(nextBoard, 'W', depth--);

			if (minPlayerEval > bestEval) {
				bestEval = minPlayerEval;
				bestMove = move;
			}
		}
		
		return bestEval;
	}

	private double minPlayerMove(Breakthrough game, char colour, int depth) {
		ArrayList<BreakthroughMove> possibleMinMoves = game
				.generateMoves(colour);

		if (game.isGameOver() || possibleMinMoves.size() == 0) {
			return MIN_EVAL;
		}

		double bestEval = MIN_EVAL;
		double eval = MIN_EVAL;
		double maxPlayerEval = MIN_EVAL;

		for (BreakthroughMove move : possibleMinMoves) {
			eval = MIN_EVAL;
			maxPlayerEval = MIN_EVAL;
			
			Breakthrough nextBoard = new Breakthrough(game);
			nextBoard.makeMove(colour, move);
			eval = evalFunction(nextBoard);

			if (eval > bestEval) {
				bestEval = eval;
			}
		}
		return bestEval;
	}

	protected double evalFunction(Breakthrough bt) {
		int row, col;
		int size = bt.size();

		for (col = 0; col < size; col++) {
			if (bt.positionOccupant(0, col) == 'W') {
				return MIN_EVAL;
			}
		}

		for (col = 0; col < size; col++) {
			if (bt.positionOccupant(size - 1, col) == 'B') {
				return MAX_EVAL;
			}
		}

		double sum = 0.0;

		for (row = 0; row < size; row++) {
			for (col = 0; col < size; col++) {
				char piece = bt.positionOccupant(row, col);
				if (piece == 'B') {
					sum += row;
				} else if (piece == 'W') {
					sum -= (size - row);
				}
			}
		}
		return sum;
	}
}